/*
 * Copyright (C) 2011 "Johan Maasing" &lt;johan@zoom.nu&gt;sed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package nu.zoom.catonine.tail;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

/**
 * A Tailer is a class that tracks and decodes a file. It fires events to
 * registered listeners when new log entries (new content) appears in the
 * tracked file.
 * 
 * @author "Johan Maasing" &lt;johan@zoom.nu&gt;
 * 
 */
public interface Tailer {

	/**
	 * Set the internal buffers size.
	 * 
	 * @param size
	 *            The size in bytes, must be > 3.
	 */
	public abstract void setReadBufferSize(int size);

	/**
	 * Set the file to follow.
	 * 
	 * @param file
	 *            The file to follow, may not be null. Must exist and be
	 *            readable.
	 * @throws FileNotFoundException
	 *             If the file can not be found.
	 * @throws IOException
	 *             If already tailing a file the previous file could not be
	 *             closed.
	 */
	public abstract void setFile(final File file)
			throws IllegalArgumentException, FileNotFoundException, IOException;

	public abstract File getFile() throws IOException;

	/**
	 * Set the character set used to decode the file. If the characterset is not
	 * supported the current characterset will be changed to the platform
	 * default.
	 * 
	 * @return The charsets display name of the charset that will be used.
	 * @param charsetName
	 *            The name of the chracter set. If null or not supported the
	 *            default character set will be used instead, i.e. this class
	 *            will silently use the default.
	 */
	public abstract String setCharSet(String charsetName);

	/**
	 * Set the regular expression that breaks log blocks.
	 * 
	 * @param pattern
	 *            The pattern, may not be null.
	 * @throws java.util.regex.PatternSyntaxException
	 */
	public abstract void setLogBlockRegularExpression(Pattern pattern)
			throws PatternSyntaxException;

	/**
	 * Get the string representation of the block breaking regular expression.
	 * 
	 * @return
	 */
	public abstract String getLogBlockRegularExpression();

	/**
	 * Indicates if the characters that breaks a log block is in the start of
	 * the log block or in the end of the log block.
	 * 
	 * @return the blockMatcherStarting
	 */
	public abstract boolean isBlockMatcherStarting();

	/**
	 * Tell if the characters that break a log block is in the start of the log
	 * block or in the end of the block.
	 * 
	 * @param blockMatcherStarting
	 *            the blockMatcherStarting to set
	 */
	public abstract void setBlockMatcherStarting(boolean blockMatcherStarting);

	/**
	 * Reset the current pattern and block matcher starting to the default
	 * value.
	 */
	public abstract void setDefaultPattern();

	/**
	 * Indicates if the tailer is tailing.
	 * 
	 * @return true if the tailer has not been told to stop and is active.
	 */
	public abstract boolean isTailing();

	/**
	 * Tell the tailer to start tailing.
	 */
	public abstract void start() throws IllegalStateException;

	/**
	 * Inform the tailer to stop.
	 */
	public abstract void stop();
	
	/**
	 * Tell the tailer to restart reading the file. Can be useful if the log block break pattern is changed and the
	 * view of the file needs to be reconstructed.
	 */
	public abstract void restart() ;

	/**
	 * Add a listener to the tailer.
	 * 
	 * @param listener
	 */
	void addListener(TailerListener listener);

	/**
	 * Remove a listener from the tailer.
	 * 
	 * @param listener
	 */
	void removeListener(TailerListener listener);
}